Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add variant picker sold out UI #105

Closed
wants to merge 1 commit into from

Conversation

cfxd
Copy link
Contributor

@cfxd cfxd commented Jul 6, 2021

Add variant picker sold out UI, just a fist iteration to get the ball rolling

Why are these changes introduced?

Fixes #45 (Variant picker).

What approach did you take?

Enable/disable options as available, including an option to allow disabled combinations to remain enabled for use with third party stock notification apps.

Demo links
Password: fleomo

Checklist

@tyleralsbury
Copy link
Contributor

Thanks for the contribution, cfxd.

Based on our code principles for Dawn, there are some issues with this Pull Request. See the contributing guidelines for the full document on code principles. In particular, this PR has an issue with the server rendered principle. The goal in Dawn, and in theme development going forward, is for Liquid to handle all of the rendering tasks and for complex client-side logic for rendering to be avoided.

This PR brings up an interesting question, though - is there a way for the Shopify platform, through Liquid alone, to help with this sort of thing?

An example would be something along the lines of having something available in the value in {%- for value in option.values -%} for the second option onwards that would say whether or not the option should be enabled, based on the selected_value of the other options. Then we could just fetch the variant picker part of the page from the server and render it directly with Liquid handling all the complex logic.

My impression is that right now the platform doesn't exactly provide what would be needed for this to be possible, but it feels like a potential road forward for this functionality to be implemented without needing to do so much heavy lifting within the JS.

@cfxd
Copy link
Contributor Author

cfxd commented Jul 13, 2021

Right on, I figured that's what you were going for based on #45 and I just wanted to get this out into the universe somehow. I do actually believe it's possible using liquid and I'm working on it!

@tyleralsbury
Copy link
Contributor

Right on, I figured that's what you were going for based on #45 and I just wanted to get this out into the universe somehow. I do actually believe it's possible using liquid and I'm working on it!

Very interesting! Feel free to update here as you go. Thanks, @cfxd .

@cfxd cfxd force-pushed the variant-picker-sold-out-ui branch 2 times, most recently from 2c00a25 to c764e83 Compare July 14, 2021 19:42
@cfxd
Copy link
Contributor Author

cfxd commented Jul 14, 2021

@tyleralsbury check it out, just forced a push with a refactor in Liquid. Some question marks but at least it's a mvc.

@gregjotau
Copy link

image

I ported over the changes to my test branch and it seems to work pretty well.

It seems to be some weird things happening "flimmering" when switching sizes fast (but not very realistic):

https://zbzqpt8y20835625-7660339297.shopifypreview.com/products/vortex-high-waist-leggings?variant=31279573762145

@cfxd great work 🙌 I hope @tyleralsbury can help merge this ASAP with needed changes as this is very "basic" need of our store.

@cfxd
Copy link
Contributor Author

cfxd commented Jul 19, 2021

Thanks @gregjotau. I believe the delay you're experiencing is due to the fetch() call which is definitely slower than using client side data and logic, but if you're doing this on a non-live theme then I do believe it should speed up a bit when the theme is published live.

@gregjotau
Copy link

@cfxd @tyleralsbury

I pushed it live on: https://famme.no/products/long-sleeve?variant=37560099471534

It works good enough for us, but of course, before merging should get some attention and cleanup :)

gregjotau
gregjotau previously approved these changes Jul 19, 2021
Copy link

@gregjotau gregjotau left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Works fine on famme.no

@cfxd
Copy link
Contributor Author

cfxd commented Jul 30, 2021

@tyleralsbury would love a code review when you have a chance please!

@cfxd cfxd force-pushed the variant-picker-sold-out-ui branch from 165b064 to 47d581f Compare August 13, 2021 18:48
@cfxd
Copy link
Contributor Author

cfxd commented Aug 13, 2021

@tyleralsbury (and @gregjotau ) I just merged this with latest changes and squashed the commits. Would love a code review please!

@gregjotau
Copy link

I have used the code for some time now on famme.no, also up to date with the latest version/commits. So 👍 from me.

@bakura10
Copy link

While the Liquid based approach works, I feel Shopify should have helper to do that more easily:

{% for option in product.options %}
  {% for value in option.values %}
    // APPROACH 1:
    {% if value.has_available_variants %}
       // This value (for instance XS) has at least one variants
    {% endif %}

     // APPROACH 2: this one would be more flexible and would also allow to simplify other use cases:
     {% assign available_variants = value.variants | where: 'available' %}
  {% endfor %}
{% endfor %}

The second approach would allows us to simplify code when we need to retrieve for instance the URL of the first available variant for a given color.

@tyleralsbury
Copy link
Contributor

Hey @cfxd , sorry I haven't looped back around to this for so long. Things were busy and I also had a bit of time off. I'm gonna be looking at this directly as well as adding it to the list of community PRs for our internal theme developers to review.

@bakura10 thanks for that suggestion - one of the things we definitely do want to do is bring these types of simplification ideas to our platform team so that theme development can be easier.

@tyleralsbury tyleralsbury self-requested a review September 2, 2021 13:31
@tyleralsbury
Copy link
Contributor

Hi @cfxd , thanks again for your contribution

I've played with this for a little while this morning and it overall works really well. I've noticed a hitch when dealing with unavailable products, though. Because an unavailable product doesn't have a variant ID, when the onVariantChange function runs, it doesn't re-render the product info via this.renderProductInfo();. As a result, the UI doesn't update in a case like that.

So for example, you can set up the following:

Variant 1 - Available in "Blue", "Small"
Variant 2 - Available in "Red", "Medium"

  1. Select the options for "Blue", "Small"
  2. Notice that "Medium" is crossed out, this is expected since "Blue" is not available in "Medium"
  3. Select "Red". Because "Small" is still selected, the product is "Unavailable" - you can see that the "Add to cart" button changes to indicate this.
  4. Notice that "Medium" is still crossed out. Since the product info didn't re-render, this hasn't changed, and thus it looks like "Medium" is unavailable. Notice also that "Small" is not crossed out.
  5. Click "Medium". The product is available in medium, so it will reload the product info, since there is now a currentVariant. Now, "Small" will be crossed out, and "Medium" will not be.

The issue is that it takes a user action, clicking on a crossed out option, to reload the product info. Unfortunately, I don't know if there's an elegant way around this in a case where we've reached an Unavailable product by clicking on "Option 1", since we are relying on the current variant ID to update the UI.

A video demonstrating this flow:

Screen.Recording.2021-09-02.at.10.24.32.AM.mov

@gregjotau
Copy link

@tyleralsbury I cannot seem to have noticed this on famme.no?

@tyleralsbury
Copy link
Contributor

tyleralsbury commented Sep 2, 2021

@tyleralsbury I cannot seem to have noticed this on famme.no?

It happens under some pretty specific circumstances.

You need to have a situation something like this:

Option 1 - Colour
Option 2 - Size

Color - Red Color - Blue
Size - Small Available Unavailable
Size - Medium Unavailable Available

So that when switching from Red / Small, you end up on Blue / Small (which is unavailable) and thus don't trigger the UI update since the currentVariant is not set, so it skips rendering the product information.

@cfxd
Copy link
Contributor Author

cfxd commented Sep 2, 2021

Hmm, this is a complex problem. If I do what some propose and simply hide or disable the unavailable options, then in this scenario a shopper would be forever stuck on Blue / Small and they couldn't switch the color or the size.

Even if they could only switch the color option, then you're right—the size re-rendering never occurs because the initial selection is not an existing configuration.

Quite a conundrum indeed.

@tyleralsbury
Copy link
Contributor

tyleralsbury commented Sep 3, 2021

Hmm, this is a complex problem. If I do what some propose and simply hide or disable the unavailable options, then in this scenario a shopper would be forever stuck on Blue / Small and they couldn't switch the color or the size.

I agree. I think crossing them out but still letting them be clickable is the right way to approach this, as you implemented it.

Even if they could only switch the color option, then you're right—the size re-rendering never occurs because the initial selection is not an existing configuration.

Quite a conundrum indeed.

It's tricky for sure, given the current reliance on the variant ID. The fact that these variants don't exist means that they can't have an ID, so we have nothing to base the update on. This is the main reason that I'm not 100% sure that Liquid provides everything we need to make this work currently.


My idea would be that we'd need the platform to have something like "each subsequent option has an awareness of the previous ones". Then we would be able to use the selected state of the first to determine the available choices for the second, and the combination of those two to determine the third.

This would also mean that we would need to have URL parameters for each of them, so that when we query the URL for the page, we would be able to say which of the choices were selected for each option. So instead of it relying on the variant to determine which options are supposed to be selected, it could rely on the options themselves.

So, going back to this table....

Option 1 - Colour
Option 2 - Size

Color - Red Color - Blue
Size - Small Available Unavailable
Size - Medium Unavailable Available

When the page is loaded, "Red / Small" would be selected, so the page would load with Medium crossed out. This is already possible, but now let's say we changed the colour to "Blue", then there's no associated variant so currently the page has nothing to reference with regards to how to properly update.

With this proposal, we'd have a property on Option 2 (in this case Size) that would have an awareness of the current selection of Option 1 and could be handled. It would be something like value.has_associated_previous_options (naming is hard) which would be a boolean.

There is a big assumption here that I'm not 100% sure about, but it's the fact that the options are actually sequential, or in other words, that the platform even has a concept of "Colour is the first option, Size is the second option". I don't know if it does.

Some downsides...

  • It adds complexity. There's now two sources of truth for what a page should render like - the current variant and the currently selected options. That might create some confusing theme code, since we would always want a valid variant ID to be taken as the primary driver for how a page is rendered if there is one. Theme code should be clear and easy to read, so this kind of complexity being added to an already complex part of the code might be overwhelming
  • Canonical URLs. I don't think this is an issue, since the canonical URL for a product is just the product itself without any URL parameters. In general URL parameters are bad for SEO, but with canonical URLs I think it's okay.

@mohinht
Copy link

mohinht commented Sep 18, 2021

Hello,

Any updates on this? Did anyone solve this problem?

Thanks!

@cfxd
Copy link
Contributor Author

cfxd commented Oct 21, 2021

@tyleralsbury What are your thoughts about involving some JS on this so that it can work in a modern way?

@gregjotau
Copy link

Second that. It is consistent with the "javascript as needed" philosophy.

Basically: What we have now is really bad, I would call it a critical bug even, to have such basic functionality missing.

@catboxer
Copy link

catboxer commented Oct 22, 2021

@cfxd Thanks so much for this. I will just make sure that all possible variants exist as out of stock products when I have more than one option avoiding the no variant id issue because IMO I'd rather have unavailable variants show as out of stock and greyed out then give the customers no signals.

@tyleralsbury
Copy link
Contributor

@tyleralsbury What are your thoughts about involving some JS on this so that it can work in a modern way?

I still think we need some platform improvements to make it easier to determine directly in the Liquid... this way the logic is not handled in the JS and can be defined by a single source of truth.

What do you think of this proposal? #105 (comment)

Do you see any issues with the idea? Any edge cases we've not considered?

@gregjotau
Copy link

@tyleralsbury for SEO I would say it is no problem, as you say as long as the canonical is set to the product url without parameters.

A platform change like that would take a lot of time I suspect, so a temporary solution with JS to make Dawn palatable is necessary IMO fast.

@gregjotau
Copy link

Any update here? This is actually hurting pretty bad. Seems to be totally broken.

https://famme.no/products/sample

I thought it always worked, but it might be because I added another kind of option setup, not sure why it is not updating properly now @cfxd on this product. Hopefully it is not more products

@tyleralsbury
Copy link
Contributor

Hey @gregjotau - it is definitely on our radar to take a look at this but is not currently slotted as a priority. We still need to sort out whether or not an approach that leverages a platform change is necessary to facilitate this. If we are implementing a feature like this, we want to make sure that it can be done in a strongly principled, well reasoned, and performant way.

@gregjotau
Copy link

@tyleralsbury any update on this? We do not want to have custom code for this as it requires more time when merging new changes in.

@tyleralsbury
Copy link
Contributor

@tyleralsbury any update on this? We do not want to have custom code for this as it requires more time when merging new changes in.

Unfortunately, we still do not have an update on this. Sorry about that. We will let you know when we do.

@gregjotau
Copy link

@tyleralsbury any new year resolutions to fix this one? :)

@gregjotau
Copy link

Are there any pending platform changes being worked upon that fixes this? 🙏 Would be great if one checked that, since if no changes is being worked upon, maybe accept some JS soultion.

@gregjotau
Copy link

Does anyone have a JS solution as a fork btw? (that is bullet proof and addresses the concerns of @tyleralsbury above)

@gregjotau
Copy link

@tyleralsbury @ludoboludo any update on this, we have a bug related to the sold out UI from this branch that is annoying:

respiro-ecommerce/dawn-famme#46

So we really need this built in and solid. I would argue this is much more important than basically everything else like mega menu (which is also awesome btw!) and small UI fixes.

@gregjotau
Copy link

@cfxd do you have a JS fix on another branch which is "bullet proof"? Would love to know if you have researched this more 🙏

@cfxd
Copy link
Contributor Author

cfxd commented Feb 24, 2022

@gregjotau @mohinht check #1407

Copy link

@kdubbelaar kdubbelaar left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sold Out variant picker

@gregjotau
Copy link

I guess this one can be closed since 1407 duplicates it?

@kdubbelaar
Copy link

kdubbelaar commented Jun 28, 2022 via email

@ludoboludo
Copy link
Contributor

I'll close this PR since we have another one open and being reviewed. 👍
We can reopen if needed.

@ludoboludo ludoboludo closed this Aug 8, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

UI Polish Review: Product Template (Part 2)
10 participants